package com.zhj.juc.demo1;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @PackageName:com.zhj.juc.demo1
 * @ClassName:Test2SaleTicket
 * @auter: 朱慧杰
 * @date:2020/7/22 0022 22:06
 **/
public class Test2SaleTicket {

    public static void main(String[] args) {

        Ticket ticket = new Ticket();

        new Thread(()->{
            for (int i = 0; i < 60; i++) {
                ticket.sale();
            }
        },"小明").start();

        new Thread(()->{
            for (int i = 0; i < 60; i++) {
                ticket.sale();
            }
        },"小红").start();

        new Thread(()->{
            for (int i = 0; i < 60; i++) {
                ticket.sale();
            }
        },"小华").start();
    }

}

// 资源类 OOP
class Ticket {

    private int number = 50;

   /* ----------------------synchronized 锁--------------------------------------------------------------
   public synchronized void sale() {
        if (number > 0) {
            System.out.println(Thread.currentThread().getName() + "买了一张票，剩余票数：" + (--number));
        }
    }*/

   // lock 锁  与  synchronized 锁
   // synchronized 1.内置关键字-------2.无法判断锁的状态-------3.会自动释放锁
   //              ---4.线程一获得锁阻塞，线程二就会一直等 ---5.可重入锁，不可中断，非公平的------6.锁少量的代码同步问题
   // lock         1.是一个java类-----2.可以判断是否获得锁-----3.需要手动释放
   //              ---4.不会一直等 ---------------------------5.可重入锁，可判断锁，非公平（可以自己设）----6.锁大量的代码
   Lock lock = new ReentrantLock();

    public void sale() {

        lock.lock();  // 加锁

        try {
            if (number > 0) {
                System.out.println(Thread.currentThread().getName() + "买了一张票，剩余票数：" + (--number));
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();  // 解锁
        }
    }

}